import copy
import io
import logging

import PIL
import numpy as np
from nicegui import ui, events

from aipl_algoimpl import AiplAlgoImpl

columns = [{'field': 'id'},
            {'field': 'age', 'editable': True},
            {'field': 'name', 'editable': True, 'sortable': True},
        ]
rows = [
    {'id': 0, 'name': 'Alice', 'age': 18},
    {'id': 1, 'name': 'Bob', 'age': 21},
    {'id': 2, 'name': 'Carol', 'age': 20},
]

class OpencvLocationFrame:
    def __init__(self, log_handler: logging.Logger):
        self.imagesrc_opencv = None
        self.logger = log_handler
        self.algo_dict = AiplAlgoImpl.get_supported_algos()
        self.algo_selected = {}
        self.aiplalgoimpl = AiplAlgoImpl()
        self._build()

    def mouse_handler_ii_init(self, e: events.MouseEventArguments):
        color = 'SkyBlue' if e.type == 'click' else 'SteelBlue'
        self.ii_src.content += f'<circle cx="{e.image_x}" cy="{e.image_y}" r="1" fill="none" stroke="{color}" stroke-width="4" />'
        ui.notify(f'{e.type} at ({e.image_x:.1f}, {e.image_y:.1f})')

    def mouse_handler_ii_processed(self, e: events.MouseEventArguments):
        color = 'SkyBlue' if e.type == 'click' else 'SteelBlue'
        self.ii_processed.content += f'<circle cx="{e.image_x}" cy="{e.image_y}" r="1" fill="none" stroke="{color}" stroke-width="4" />'
        ui.notify(f'{e.type} at ({e.image_x:.1f}, {e.image_y:.1f})')
    def handle_plpic_upload(self, e: events.UploadEventArguments):
        self.logger.debug('handle DAF upload')
        imgsrc_filedata = e.content.read()

        # 使用BytesIO将字节数据转为文件对象
        imagesrc_bytes = io.BytesIO(imgsrc_filedata)

        # img_cv2 = cv2.imdecode(np.asarray(bytearray(bytes_data), dtype='uint8'), cv2.IMREAD_COLOR)

        # 使用PIL的Image类从文件对象中读取图像
        self.imagesrc_pil = PIL.Image.open(imagesrc_bytes)

        # 如果需要转换为OpenCV的图像格式
        self.imagesrc_opencv = np.array(self.imagesrc_pil)

        self.logger.debug(f'uploaded file length={len(imgsrc_filedata)}')

        self.ii_src.set_source(self.imagesrc_pil)
        # content.set_content(text)
        # dialog.open()

    def do_image_processing(self):
        print(f'selected algo={self.select_algo_list.value}')
        if len(self.select_algo_list.value) < 1:
            self.ii_processed.set_source(self.imagesrc_pil)
        else:
            img = copy.copy(self.imagesrc_opencv)
            img_pil = PIL.Image.fromarray(self.imagesrc_opencv)
            for algo in list(self.select_algo_list.value):
                if algo == 'openning':
                    img, img_pil = self.aiplalgoimpl.opencv_openning(img, (5, 5))
                elif algo == 'grey':
                    img, img_pil = self.aiplalgoimpl.opencv_grey(img)
                elif algo == 'gaussblur':
                    img, img_pil = self.aiplalgoimpl.opencv_guass_blur(img)
                elif algo == 'medianblur':
                    img, img_pil = self.aiplalgoimpl.opencv_median_blur(img)
                elif algo == 'sobelblur':
                    img, img_pil= self.aiplalgoimpl.opencv_sobel_blur(img)
                elif algo == 'cannyblur':
                    img, img_pil = self.aiplalgoimpl.opencv_canny_blur(img)
                elif algo == 'threshold':
                    img, img_pil = self.aiplalgoimpl.opencv_threshold(img, 127, 255)
                elif algo == 'contours':
                    img, img_pil = self.aiplalgoimpl.opencv_find_contours(img)
                elif algo == 'erode':
                    img, img_pil = self.aiplalgoimpl.opencv_erode(img)
                else:
                    pass

            self.logger.debug(f'the type of processed image={type(img)}')
            self.ii_processed.set_source(img_pil)

    def add_row(self):
        new_id = max((dx['id'] for dx in rows), default=-1) + 1
        rows.append({'id': new_id, 'name': 'New name', 'age': None})
        ui.notify(f'Added row with ID {new_id}')
        self.aggrid.update()

    def handle_cell_value_change(e):
        new_row = e.args['data']
        ui.notify(f'Updated row to: {e.args["data"]}')
        rows[:] = [row | new_row if row['id'] == new_row['id'] else row for row in rows]

    async def delete_selected(self):
        selected_id = [row['id'] for row in await self.aggrid.get_selected_rows()]
        rows[:] = [row for row in rows if row['id'] not in selected_id]
        ui.notify(f'Deleted row with ID {selected_id}')
        self.aggrid.update()
    def _build(self):
        with ui.row().classes('w-full items-end justify-items-end'):
            ui.label('产线定位检测').classes('text-h6 font-bold')
        with ui.row().classes('w-full items-end justify-items-end'):
            ui.upload(label='产线照片上传', on_upload=self.handle_plpic_upload).props(
                'accept=.jpg no-thumbnails color=blue-11').classes('max-w-full')
            label_plpic_upload = ui.label('').classes('italic text-xs text-red-600 text-opacity-75')
        ui.separator()
        with ui.row().classes('w-full items-end justify-items-end'):
            self.aggrid = ui.aggrid({
                'columnDefs': columns, 'rowData': rows, 'rowSelection': 'multiple', 'stopEditingWhenCellsLoseFocus': True,
            }).on('cellValueChanged', self.handle_cell_value_change)

            ui.button('Delete selected', on_click=self.delete_selected)
            ui.button('New row', on_click=self.add_row)
        ui.separator()
        with ui.row().classes('w-full items-end justify-items-end'):
            self.select_algo_list = ui.select(options=self.algo_dict, multiple=True, label='已选算法列表',
                                              value=self.algo_selected).classes('w-full').props('use-chips')
            self.btn_connect = ui.button('执行选中算法', on_click=self.do_image_processing).props('color=blue')
        with ui.row().classes('w-full items-end justify-items-end'):
            with ui.column().classes('w-full h-full'):
                src = 'https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png'
                ui.label('原始图像')
                self.ii_src = ui.interactive_image(src, on_mouse=self.mouse_handler_ii_init, events=['mousedown', 'mouseup'],
                                                   cross='red')
                ui.label('处理后图像')
                self.ii_processed = ui.interactive_image(src, on_mouse=self.mouse_handler_ii_processed, events=['mousedown', 'mouseup'],
                                                     cross='red')
